import express from 'express';
import path from 'path';
import fs from 'fs-extra';
import http from 'http';
import { WebSocket, WebSocketServer } from 'ws';
import { ComponentParser } from '../parser/parser';
import { generateMarkdown } from '../generator/markdownGenerator';
import { generateHtml } from '../generator/htmlGenerator';
import { FileChangeEvent, FileWatcher } from './watcher';

/**
 * 广播消息给所有连接的WebSocket客户端
 * @param wss WebSocket服务器
 * @param message 消息对象
 */
function broadcast(wss: WebSocketServer, message: any): void {
  const data = JSON.stringify(message);
  wss.clients.forEach(client => {
    if (client.readyState === WebSocket.OPEN) {
      client.send(data);
    }
  });
}

/**
 * 启动组件文档服务器
 * @param scanPaths 要扫描的组件路径
 * @param port 服务器端口
 * @param vueVersion Vue版本
 * @param parser 组件解析器实例（可选）
 */
export async function startServer(
  scanPaths: string[],
  port: number,
  vueVersion: string = 'auto',
  parser?: ComponentParser
): Promise<void> {
  const app = express();
  const server = http.createServer(app);
  const wss = new WebSocketServer({ server });
  
  // 创建或使用提供的解析器
  const componentParser = parser || new ComponentParser(scanPaths, vueVersion);
  
  // 初始化文件监控器
  const watcher = new FileWatcher(scanPaths, componentParser);
  
  // 监听文件变更事件
  watcher.on('change', async (event: FileChangeEvent) => {
    console.log(`检测到文件变更，类型: ${event.type}, 路径: ${event.path}`);
    
    // 广播更新消息给客户端
    broadcast(wss, {
      type: 'components-updated',
      timestamp: new Date().toISOString(),
      event: event
    });
  });
  
  // 解析组件信息
  await componentParser.parseComponents();
  
  // 启动文件监控
  watcher.start();
  
  // 静态资源目录
  const staticDir = path.join(__dirname, '../../public');
  app.use(express.static(staticDir));
  
  // API路由
  app.get('/api/components', (req, res) => {
    // 为前端提供一个修改过的组件列表，其中包含编码后的ID
    const components = componentParser.getComponentList().map(component => ({
      ...component,
      // 添加一个编码后的ID，用于路由
      encodedId: Buffer.from(component.id).toString('base64')
    }));
    res.json(components);
  });
  
  // 使用编码后的ID获取组件
  app.get('/api/component/:encodedId', (req, res) => {
    try {
      // 解码组件ID
      const componentId = Buffer.from(req.params.encodedId, 'base64').toString();
      console.log(`获取组件, 编码ID: ${req.params.encodedId}, 解码后: ${componentId}`);
      
      const component = componentParser.getComponentById(componentId);
      
      if (component) {
        res.json(component);
      } else {
        res.status(404).json({ error: '组件未找到' });
      }
    } catch (error) {
      console.error('解码组件ID失败:', error);
      res.status(400).json({ error: '无效的组件ID' });
    }
  });
  
  // 导出Markdown
  app.get('/api/export/markdown', async (req, res) => {
    try {
      const outputPath = path.join(process.cwd(), 'vuelens-export-md');
      await generateMarkdown(scanPaths, outputPath, vueVersion, componentParser);
      res.json({ success: true, path: outputPath });
    } catch (error) {
      res.status(500).json({ 
        error: '导出Markdown失败', 
        message: error instanceof Error ? error.message : String(error) 
      });
    }
  });
  
  // 导出HTML
  app.get('/api/export/html', async (req, res) => {
    try {
      const outputPath = path.join(process.cwd(), 'vuelens-export-html');
      await generateHtml(scanPaths, outputPath, vueVersion, componentParser);
      res.json({ success: true, path: outputPath });
    } catch (error) {
      res.status(500).json({ 
        error: '导出HTML失败', 
        message: error instanceof Error ? error.message : String(error) 
      });
    }
  });
  
  // 解析器信息
  app.get('/api/parser-info', (req, res) => {
    res.json({
      type: componentParser.constructor.name,
      vueVersion: vueVersion,
      lastUpdateTime: componentParser.getLastUpdateTime(),
      componentCount: componentParser.getComponentList().length
    });
  });
  
  // WebSocket连接
  wss.on('connection', (ws) => {
    console.log('WebSocket客户端已连接');
    
    // 发送初始化消息
    ws.send(JSON.stringify({
      type: 'connected',
      message: 'WebSocket连接已建立',
      timestamp: new Date().toISOString()
    }));
    
    // 处理消息
    ws.on('message', (message) => {
      try {
        console.log('收到消息:', message.toString());
      } catch (error) {
        console.error('解析WebSocket消息失败:', error);
      }
    });
    
    // 处理连接关闭
    ws.on('close', () => {
      console.log('WebSocket客户端已断开连接');
    });
  });
  
  // 所有其他请求都返回index.html
  app.get('*', (req, res) => {
    res.sendFile(path.join(staticDir, 'index.html'));
  });
  
  // 启动服务器
  return new Promise((resolve, reject) => {
    try {
      server.listen(port, () => {
        console.log(`VueLens 服务器已启动，端口: ${port}`);
        console.log(`扫描路径: ${scanPaths.join(', ')}`);
        console.log(`已解析 ${componentParser.getComponentList().length} 个组件`);
        console.log(`访问 http://localhost:${port} 查看组件文档`);
        resolve();
      });
    } catch (err) {
      reject(err);
    }
  });
} 